package constants

import (
	"fmt"
)

func DefineConstants() {

	const Pi float64 = 3.14159265358
	fmt.Println(Pi)

	const zero = 0.0
	fmt.Println(zero)

	//警惕
	//SA9004 - Only the first constant has an explicit type
	// In a constant declaration such as the following
	// const (
	// 	size float64 = 1024
	// 	eof          = -1
	// )

	const (
		size float64 = 1024
		eof  float32 = -1
	)

	fmt.Println(size, eof)

	const u, v float32 = 0, 3
	fmt.Println(u, v)

	const a, b, c = 3, 4, "foo"
	fmt.Println(a, b, c)

	// 常量定义的右值也可以是一个在编译期运算的常量表达式
	const mask = 1 << 3
	fmt.Println(mask)
	//警惕
	//由于常量的赋值是一个编译期行为，所以右值不能出现任何需要运行期才能得出结果的表达式
	// const Home = os.Getenv("GOPATH")
}

/*
演示GO语言预定义常量, true、false和iota。
*/
func PreDefineConstants() {

	//iota比较特殊，可以被认为是一个可被编译器修改的常量，在每一个const关键字出现时被
	//重置为0，然后在下一个const出现之前，每出现一次iota，其所代表的数字会自动增1。
	const ( //iota被重设为0
		c0 = iota //c0 == 0
		c1 = iota //c1 == 0
		c2 = iota //c2 == 0
	)

	fmt.Println(c0, c1, c2)
	const (
		a = 1 << iota // a == 1 (iota在每个 const开头被重设为0)
		b = 1 << iota // b == 2
		c = 1 << iota // c == 4
	)

	fmt.Println(a, b, c)
	const (
		u         = iota * 24 // u == 0
		v float64 = iota * 24 // v == 42.0
		w         = iota * 42 // w == 84
	)

	fmt.Println(u, v, w)

	const x = iota // x == 0 (因为iota又被重设为0了)
	const y = iota // y == 0 (因为iota又被重设为0了)
	fmt.Println(x, y)

	//如果两个const的赋值语句的表达式是一样的，那么可以省略后一个赋值表达式
	const (
		d0 = iota
		d1
		d2
	)
	fmt.Println(d0, d1, d2)

	const (
		xa = 1 << iota // a == 1 (iota在每个const开头被重设为0)
		xb             // a == 1 (iota在每个const开头被重设为0)
		xc             // a == 1 (iota在每个const开头被重设为0)
	)

	fmt.Println(xa, xb, xc)

}
